/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package serverv2_0;
import java.io.* ;
import java.net.* ;
import java.util.* ;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
/**
 *
 * @author suhui
 */
public class TCPReceive implements Runnable{
  
    players playerlist;
    private Socket socket;
    private BufferedReader inFromClient;
    int status = 0;
    Hashtable msg_hashed = new Hashtable();
    
            public TCPReceive(Socket socket, players playerlist) throws Exception{
                this.socket = socket;
                this.playerlist = playerlist;
            }

            public void run()
            {
                try
                {
                    print("processing");
                    processRequest();
                }
                catch (Exception e)
                {
                    sendstatus(100);
                    System.out.println(e);
                }

            }
            void processRequest ()throws Exception
            {
                //create input reader
                inFromClient = new BufferedReader(new InputStreamReader(socket.getInputStream()));

               //process commandtype
               try
               {

                   getfields(readline());
                }
               catch(Exception e)
               {
                   sendstatus(100);
               }
               String packettype = findinHash("type");
                print("This is a " + packettype + " packet");
                if (packettype.equals("command"))
                {
                    processcommand();
                }
                else if (packettype.equals("data"))
                {
                    processdata();

                }
                else if (packettype.equals("reply"))
                {
                    processping();
                }
                 else
                     sendstatus(100);
              
	
            }
            void processping()
            {
                for( int i = 0 ; i < playerlist.toping.size();i++)
                {
                    if(playerlist.toping.get(i).ipaddress.equals(socket.getInetAddress().toString()))
                    {
                        playerlist.toping.remove(i);
                    }

                }
            }

            void processdata()
            {
                print("processing data");

                String user = findinHash("username");
                int experience = Integer.parseInt(findinHash("exp_gained"));

                if(user == null)
                {
                    print("invalid user");
                    sendstatus(100); //error in received string
                }
                else
                {
                    print(user + " + " + String.valueOf(experience) + " points" );
                    boolean successful = playerlist.addexperience(user,experience);
                    
                    if(successful)
                    {
                        print("successful update");
                        sendstatus(1);
                    }
                    else
                    {
                        sendstatus(3); //invalid user
                        print("error in update");
                    }
                }




            }
            void processcommand()
            {
                print("processing commands");
                String action = findinHash("action");
                
                
                if(action.equals("register")||action.equals("login"))
                {
                    
                    String user = findinHash("user");
                    String password = findinHash("password");

                    print(action +"-ing "+user);

                    if(user == null||password == null)
                    {
                        print("no username or password found");
                        sendstatus(100);
                    }
                    else if(action.equals("register"))
                    {

                        boolean success = playerlist.addnew(user, password, socket.getInetAddress());
                        if(success)
                        {
                            print("registration successful");
                            sendstatus(4);
                        }
                            else
                        {
                            print("registration unsuccessful, username in use");
                                sendstatus(5);
                        }
                    }
                    else
                    {
                        int success = playerlist.login(user, password,socket.getInetAddress() ) ;
                        if(success == 1)
                        {
                            print("login successful \n" +user +" online");
                            sendstatus(1);

                        }
                        else if(success == 2)
                        {
                            print("invalid password");
                            sendstatus(2);
                        }
                            else
                        {
                            print("no such user");
                            sendstatus(3);
                        }
                    }
                }
                else if (action.equals("send_client_list"))
                {
                    print("player wants to know who is on");
                    sendstatus(6);
                }
                else
                {
                    print("no such command");
                    sendstatus(100);
                }

            }

            private String findinHash(String key)
            {
                return (String) msg_hashed.get(key);
            }
            private boolean getfields(String message)
            {
                print(message);
                String[] msg_array = message.split(";");
                
                for(String i :msg_array){
                    String[] row = i.split(":");
                    msg_hashed.put(row[0], row[1]);
                }
                printhash(msg_hashed);
                //System.out.println("testing "+msg_hashed.get("user"));

                return true;


            }


            String readline()
    {
                    String receivedd="";
                try
                {
                    Thread.sleep(100);
                    while(inFromClient.ready())
                        receivedd += (char)inFromClient.read();
                     //= inFromClient.readLine();
                    print(receivedd);
                    return receivedd;
                }
                catch (Exception e)
                {
                    print("nothing to read");
                    return "";
                }
            }
            void sendstatus(int type)
            {
                String reply = "type:reply;status:";
                print("Constructing Reply");
                switch(type)
                {
                    case 1: reply = reply.concat("ok;");
                    break;
                    case 2: reply = reply.concat("wrong_pass;");
                    break;
                    case 3: reply = reply.concat("invalid_user;");
                    break;
                    case 4: reply = reply.concat("reg_successful;");
                    break;
                    case 5: reply = reply.concat("reg_unsuccessful;");
                    break;
                    case 6:
                            reply = playerlist.getonlinelist();
                        break;
                    case 100: reply = reply.concat("error;");
                    break;
                    default: reply="";
                    break;

                }
                try
                {
                    print("sending reply");
                    //Socket returnsocket = new Socket(socket.getInetAddress(), 4000);

                    DataOutputStream outToClient = new DataOutputStream(socket.getOutputStream());
				
                    outToClient.writeBytes(reply  );

                    outToClient.close();
                    inFromClient.close();
                    socket.close();
                }
                catch (Exception e)
                {
                    print("error connecting to host");
                    System.out.println(e);
                }

                }

            void print(String toprint)
            {
                System.out.println(toprint);
            }
            public void printhash (Hashtable ht)
            {
                Enumeration enum1 = ht.keys ();
                while (enum1.hasMoreElements ()) {
                String key = (String) enum1.nextElement ();
                String value = (String) ht.get (key);
                System.out.println ("{ " + key + ", " + value + " }");
            }
    }
}
